package com.aplink.generic.network;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Locale;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;

import com.aplink.generic.constant.HandlerConstant;
import com.aplink.generic.util.LogUtil;

public class DownloadManager extends
        AsyncTask<String, Integer, ArrayList<String>> {
    private final Context mContext;
    private final Handler mHandler;
    private final String mLocalPath;
    private ProgressDialog mProgress;

    public DownloadManager(final Context context, final Handler handler,
            final String localPath) {
        this.mContext = context;
        this.mHandler = handler;
        this.mLocalPath = localPath;
    }

    @Override
    protected ArrayList<String> doInBackground(final String... params) {
        final ArrayList<String> localPaths = new ArrayList<String>();
        for (int i = 0; i < params.length; i++) {
            try {
                final String physicalPath = params[i];
                final URL url = new URL(physicalPath);
                final URLConnection connection = url.openConnection();
                final int fileSize = connection.getContentLength();
                int currentSize = 0;
                final InputStream input = connection.getInputStream();

                publishProgress(0, i, params.length);

                final String temporaryName = String.format(Locale.getDefault(),
                        "%d.jpg", System.currentTimeMillis());
                final File storagePath = new File(this.mLocalPath,
                        temporaryName);
                final OutputStream output = new FileOutputStream(storagePath);
                try {
                    final byte[] buffer = new byte[1024];
                    int bytesRead = 0;
                    while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
                        output.write(buffer, 0, bytesRead);
                        currentSize += 1024;
                        final float percent = (float) currentSize
                                / (float) fileSize;
                        publishProgress((int) (percent * 100));
                    }
                    LogUtil.info(
                            "downloaded: " + "file://" + storagePath.toString(),
                            "Download file:" + params[i], getClass());
                    localPaths.add(storagePath.toString());
                } finally {
                    output.close();
                }
            } catch (final IOException e) {
                LogUtil.error(e.getMessage(), "Download file:" + params[i],
                        getClass());
                e.printStackTrace();
            }
        }
        return localPaths;
    }

    @Override
    protected void onPostExecute(final ArrayList<String> result) {
        super.onPostExecute(result);
        this.mProgress.dismiss();
        this.mHandler.obtainMessage(HandlerConstant.DOWNLOAD_FILE_RESULT,
                result).sendToTarget();
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        this.mProgress = new ProgressDialog(this.mContext);
        this.mProgress.setCancelable(false);
        this.mProgress.setCanceledOnTouchOutside(false);
        this.mProgress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        this.mProgress.setProgress(0);
        this.mProgress.setMessage("File downloading ...");
        this.mProgress.setMax(100);
        this.mProgress.show();
    }

    @Override
    protected void onProgressUpdate(final Integer... values) {
        super.onProgressUpdate(values);
        this.mProgress.setProgress(values[0]);
        if (values.length > 1) {
            this.mProgress.setMessage("File downloading ..." + (values[1] + 1)
                    + "/" + values[2]);
        }
    }

}
